package com.cardcaptorsakura.model.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.List;
import java.util.Map;

/**
 * 聊天请求DTO
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatRequest {

    /**
     * 请求ID
     */
    private String requestId;

    /**
     * 用户ID
     */
    @NotBlank(message = "用户ID不能为空")
    private String userId;

    /**
     * 用户输入文本
     */
    @NotBlank(message = "输入文本不能为空")
    @Size(max = 4000, message = "输入文本长度不能超过4000字符")
    private String text;

    /**
     * 会话ID
     */
    private String conversationId;

    /**
     * 消息类型
     */
    @Builder.Default
    private MessageType messageType = MessageType.TEXT;

    /**
     * 上下文消息列表
     */
    private List<ContextMessage> contextMessages;

    /**
     * 系统提示词
     */
    private String systemPrompt;

    /**
     * 温度参数（0.0-2.0）
     */
    @Builder.Default
    private Double temperature = 0.7;

    /**
     * 最大输出长度
     */
    @Builder.Default
    private Integer maxLength = 2000;

    /**
     * Top-p参数（0.0-1.0）
     */
    @Builder.Default
    private Double topP = 0.9;

    /**
     * Top-k参数
     */
    @Builder.Default
    private Integer topK = 50;

    /**
     * 重复惩罚（0.0-2.0）
     */
    @Builder.Default
    private Double repetitionPenalty = 1.1;

    /**
     * 是否流式输出
     */
    @Builder.Default
    private Boolean stream = false;

    /**
     * 停止词列表
     */
    private List<String> stopWords;

    /**
     * 处理选项
     */
    private MultiModalOutputRequest.ProcessingOptions options;

    /**
     * 优先级（1-10）
     */
    @Builder.Default
    private Integer priority = 5;

    /**
     * 超时时间（秒）
     */
    @Builder.Default
    private Integer timeout = 60;

    /**
     * 额外参数
     */
    private Map<String, Object> extraParams;

    /**
     * 消息类型枚举
     */
    public enum MessageType {
        TEXT,           // 纯文本消息
        MULTIMODAL,     // 多模态消息
        SYSTEM,         // 系统消息
        ASSISTANT,      // 助手消息
        FUNCTION_CALL,  // 函数调用
        FUNCTION_RESULT // 函数结果
    }

    /**
     * 上下文消息
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ContextMessage {
        /**
         * 消息角色
         */
        private String role; // user, assistant, system

        /**
         * 消息内容
         */
        private String content;

        /**
         * 消息时间戳
         */
        private Long timestamp;

        /**
         * 消息ID
         */
        private String messageId;

        /**
         * 消息类型
         */
        private MessageType type;

        /**
         * 附加数据
         */
        private Map<String, Object> metadata;

        /**
         * 消息权重（影响上下文重要性）
         */
        @Builder.Default
        private Double weight = 1.0;

        /**
         * 是否包含在上下文中
         */
        @Builder.Default
        private Boolean includeInContext = true;
    }

    /**
     * 生成参数配置
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class GenerationConfig {
        /**
         * 创意度（0.0-1.0）
         */
        @Builder.Default
        private Double creativity = 0.7;

        /**
         * 一致性（0.0-1.0）
         */
        @Builder.Default
        private Double consistency = 0.8;

        /**
         * 详细程度（0.0-1.0）
         */
        @Builder.Default
        private Double verbosity = 0.5;

        /**
         * 正式程度（0.0-1.0）
         */
        @Builder.Default
        private Double formality = 0.5;

        /**
         * 情感强度（0.0-1.0）
         */
        @Builder.Default
        private Double emotionalIntensity = 0.5;

        /**
         * 幽默程度（0.0-1.0）
         */
        @Builder.Default
        private Double humor = 0.3;

        /**
         * 专业程度（0.0-1.0）
         */
        @Builder.Default
        private Double professionalism = 0.7;

        /**
         * 个性化程度（0.0-1.0）
         */
        @Builder.Default
        private Double personalization = 0.8;
    }

    /**
     * 内容过滤配置
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ContentFilterConfig {
        /**
         * 是否启用内容过滤
         */
        @Builder.Default
        private Boolean enabled = true;

        /**
         * 过滤严格程度（LOW, MEDIUM, HIGH）
         */
        @Builder.Default
        private String strictness = "MEDIUM";

        /**
         * 自定义过滤词列表
         */
        private List<String> customFilterWords;

        /**
         * 允许的主题列表
         */
        private List<String> allowedTopics;

        /**
         * 禁止的主题列表
         */
        private List<String> forbiddenTopics;

        /**
         * 是否记录过滤日志
         */
        @Builder.Default
        private Boolean logFiltering = true;
    }

    /**
     * 获取有效的上下文消息数量
     */
    public int getEffectiveContextSize() {
        if (contextMessages == null) {
            return 0;
        }
        
        return (int) contextMessages.stream()
                .filter(msg -> msg.getIncludeInContext())
                .count();
    }

    /**
     * 获取上下文总字符数
     */
    public int getContextCharacterCount() {
        if (contextMessages == null) {
            return 0;
        }
        
        return contextMessages.stream()
                .filter(msg -> msg.getIncludeInContext())
                .mapToInt(msg -> msg.getContent() != null ? msg.getContent().length() : 0)
                .sum();
    }

    /**
     * 获取预估token数量
     */
    public int getEstimatedTokenCount() {
        int baseTokens = text != null ? text.length() / 4 : 0; // 粗略估算：4字符≈1token
        int contextTokens = getContextCharacterCount() / 4;
        int systemTokens = systemPrompt != null ? systemPrompt.length() / 4 : 0;
        
        return baseTokens + contextTokens + systemTokens;
    }

    /**
     * 检查是否需要截断上下文
     */
    public boolean needsContextTruncation(int maxContextTokens) {
        return getContextCharacterCount() / 4 > maxContextTokens;
    }

    /**
     * 获取截断后的上下文消息
     */
    public List<ContextMessage> getTruncatedContext(int maxContextTokens) {
        if (contextMessages == null || contextMessages.isEmpty()) {
            return contextMessages;
        }
        
        List<ContextMessage> truncated = new java.util.ArrayList<>();
        int currentTokens = 0;
        int maxChars = maxContextTokens * 4; // 粗略转换
        
        // 从最新的消息开始，向前添加
        for (int i = contextMessages.size() - 1; i >= 0; i--) {
            ContextMessage msg = contextMessages.get(i);
            if (!msg.getIncludeInContext()) {
                continue;
            }
            
            int msgChars = msg.getContent() != null ? msg.getContent().length() : 0;
            if (currentTokens + msgChars <= maxChars) {
                truncated.add(0, msg); // 添加到开头
                currentTokens += msgChars;
            } else {
                break;
            }
        }
        
        return truncated;
    }

    /**
     * 验证请求参数
     */
    public boolean isValid() {
        if (userId == null || userId.trim().isEmpty()) {
            return false;
        }
        
        if (text == null || text.trim().isEmpty()) {
            return false;
        }
        
        if (temperature != null && (temperature < 0.0 || temperature > 2.0)) {
            return false;
        }
        
        if (topP != null && (topP < 0.0 || topP > 1.0)) {
            return false;
        }
        
        if (maxLength != null && maxLength <= 0) {
            return false;
        }
        
        return true;
    }

    /**
     * 获取生成配置摘要
     */
    public String getConfigSummary() {
        return String.format("temp=%.1f, maxLen=%d, topP=%.1f, topK=%d", 
                temperature, maxLength, topP, topK);
    }

    /**
     * 创建系统消息
     */
    public static ContextMessage createSystemMessage(String content) {
        return ContextMessage.builder()
                .role("system")
                .content(content)
                .type(MessageType.SYSTEM)
                .timestamp(System.currentTimeMillis())
                .weight(1.5) // 系统消息权重更高
                .build();
    }

    /**
     * 创建用户消息
     */
    public static ContextMessage createUserMessage(String content) {
        return ContextMessage.builder()
                .role("user")
                .content(content)
                .type(MessageType.TEXT)
                .timestamp(System.currentTimeMillis())
                .build();
    }

    /**
     * 创建助手消息
     */
    public static ContextMessage createAssistantMessage(String content) {
        return ContextMessage.builder()
                .role("assistant")
                .content(content)
                .type(MessageType.TEXT)
                .timestamp(System.currentTimeMillis())
                .build();
    }

    /**
     * 添加上下文消息
     */
    public void addContextMessage(ContextMessage message) {
        if (contextMessages == null) {
            contextMessages = new java.util.ArrayList<>();
        }
        contextMessages.add(message);
    }

    /**
     * 添加用户消息到上下文
     */
    public void addUserMessage(String content) {
        addContextMessage(createUserMessage(content));
    }

    /**
     * 添加助手消息到上下文
     */
    public void addAssistantMessage(String content) {
        addContextMessage(createAssistantMessage(content));
    }

    /**
     * 添加系统消息到上下文
     */
    public void addSystemMessage(String content) {
        addContextMessage(createSystemMessage(content));
    }

    /**
     * 清空上下文
     */
    public void clearContext() {
        if (contextMessages != null) {
            contextMessages.clear();
        }
    }

    /**
     * 获取最后一条用户消息
     */
    public ContextMessage getLastUserMessage() {
        if (contextMessages == null) {
            return null;
        }
        
        return contextMessages.stream()
                .filter(msg -> "user".equals(msg.getRole()))
                .reduce((first, second) -> second)
                .orElse(null);
    }

    /**
     * 获取最后一条助手消息
     */
    public ContextMessage getLastAssistantMessage() {
        if (contextMessages == null) {
            return null;
        }
        
        return contextMessages.stream()
                .filter(msg -> "assistant".equals(msg.getRole()))
                .reduce((first, second) -> second)
                .orElse(null);
    }
}